
#include <materialdatalistmodel.h>
#include <stdio.h>

MaterialDataListModel::MaterialDataListModel ()
  : QAbstractItemModel ()
  , _delegator (0)
{

}

void MaterialDataListModel::SetDelegator (MaterialDataDelegator* delegator)
{
  _delegator = delegator;
  Changed ();
}


MaterialData* MaterialDataListModel::GetMaterialData(int row)
{
  if (!_delegator)
    {
      return 0;
    }
  return _delegator->GetMaterialData(row);
}


void MaterialDataListModel::Changed ()
{
  beginResetModel();
  reset ();
  endResetModel();
}


int MaterialDataListModel::columnCount (const QModelIndex& parent) const
{
  return 1;
}

QVariant MaterialDataListModel::data (const QModelIndex& index, int role) const
{
  if (!_delegator) return QVariant();
  if (!index.isValid()) return QVariant();
  if (role != Qt::DisplayRole) return QVariant ();

  MaterialData* materialData = static_cast<MaterialData*>(index.internalPointer());
  if (!materialData) return QVariant ();

  QString name = materialData->GetCategory().GetFullName() + "." + materialData->GetFullname();
  return QVariant (name);
}


QModelIndex MaterialDataListModel::index (int row, int column, const QModelIndex& parent) const
{
  if (!_delegator) return QModelIndex();
  if (parent.isValid()) return QModelIndex ();
  if (column != 0) return QModelIndex();

  MaterialData* data = _delegator->GetMaterialData(row);

  return createIndex(row, column, data);
}

QModelIndex MaterialDataListModel::parent (const QModelIndex& index) const
{
  return QModelIndex();
}


int MaterialDataListModel::rowCount (const QModelIndex& parent) const
{
  if (!_delegator) return 0;
  if (parent.isValid()) return 0;
  return _delegator->GetNumberOfMaterialDatas();
}


AllShaderDelegator::AllShaderDelegator(MaterialManager *manager)
  : MaterialDataDelegator()
  , _manager (manager)
{
}

void AllShaderDelegator::SetMaterialManager(MaterialManager *manager)
{
  _manager = manager;
}

int AllShaderDelegator::GetNumberOfMaterialDatas() const
{
  if(!_manager)
    {
      return 0;
    }
  return _manager->GetNumberOfShaders();
}

MaterialData* AllShaderDelegator::GetMaterialData(int idx)
{
  if (!_manager)
    {
      return 0;
    }
  if (idx < 0 || idx >= _manager->GetNumberOfShaders())
    {
      return 0;
    }
  return _manager->GetShader(idx);
}


AllProgramShaderDelegator::AllProgramShaderDelegator(Program::ShaderProgram *program)
  : MaterialDataDelegator()
  , _program (program)
{
}

void AllProgramShaderDelegator::SetProgram(Program::ShaderProgram *program)
{
  _program = program;
}


int AllProgramShaderDelegator::GetNumberOfMaterialDatas() const
{
  if (!_program)
    {
      return 0;
    }
  return _program->GetNumberOfShaders();
}

MaterialData* AllProgramShaderDelegator::GetMaterialData(int idx)
{
  if (!_program)
    {
      return 0;
    }
  if (idx < 0 || idx >= _program->GetNumberOfShaders())
    {
      return 0;
    }
  return _program->GetShader(idx);
}



AllProgramDelegator::AllProgramDelegator(MaterialManager *manager)
  : MaterialDataDelegator()
  , _manager (manager)
{
}

void AllProgramDelegator::SetMaterialManager(MaterialManager *manager)
{
  _manager = manager;
}

int AllProgramDelegator::GetNumberOfMaterialDatas() const
{
  if(!_manager)
    {
      return 0;
    }
  return _manager->GetNumberOfPrograms();
}

MaterialData* AllProgramDelegator::GetMaterialData(int idx)
{
  if (!_manager)
    {
      return 0;
    }
  if (idx < 0 || idx >= _manager->GetNumberOfPrograms())
    {
      return 0;
    }
  return _manager->GetProgram(idx);
}




AllEffectDelegator::AllEffectDelegator(MaterialManager *manager)
  : MaterialDataDelegator()
  , _manager (manager)
{
}

void AllEffectDelegator::SetMaterialManager(MaterialManager *manager)
{
  _manager = manager;
}

int AllEffectDelegator::GetNumberOfMaterialDatas() const
{
  if(!_manager)
    {
      return 0;
    }
	return _manager->GetNumberOfEffects();
}

MaterialData* AllEffectDelegator::GetMaterialData(int idx)
{
  if (!_manager)
    {
      return 0;
    }
  if (idx < 0 || idx >= _manager->GetNumberOfEffects())
    {
      return 0;
    }
  return _manager->GetEffect(idx);
}


AllTextureDelegator::AllTextureDelegator(MaterialManager *manager)
  : MaterialDataDelegator()
  , _manager (manager)
{
}

void AllTextureDelegator::SetMaterialManager(MaterialManager *manager)
{
  _manager = manager;
}

int AllTextureDelegator::GetNumberOfMaterialDatas() const
{
  if(!_manager)
    {
      return 0;
    }
  return _manager->GetNumberOfTextures();
}

MaterialData* AllTextureDelegator::GetMaterialData(int idx)
{
  if (!_manager)
    {
      return 0;
    }
  if (idx < 0 || idx >= _manager->GetNumberOfTextures())
    {
      return 0;
    }
  return _manager->GetTexture(idx);
}


AllMaterialDelegator::AllMaterialDelegator(MaterialManager *manager)
  : MaterialDataDelegator()
  , _manager (manager)
{
}

void AllMaterialDelegator::SetMaterialManager(MaterialManager *manager)
{
  _manager = manager;
}

int AllMaterialDelegator::GetNumberOfMaterialDatas() const
{
  if(!_manager)
    {
      return 0;
    }
  return _manager->GetNumberOfMaterials();
}

MaterialData* AllMaterialDelegator::GetMaterialData(int idx)
{
  if (!_manager)
    {
      return 0;
    }
  if (idx < 0 || idx >= _manager->GetNumberOfMaterials())
    {
      return 0;
    }
  return _manager->GetMaterial(idx);
}

MaterialDataSortFilterProxModel::MaterialDataSortFilterProxModel (MaterialDataListModel* model, QObject* parent)
  : QSortFilterProxyModel(parent)
  , _model(model)
{

  setSourceModel(model);
  SetFilter("");
}

void MaterialDataSortFilterProxModel::ModelChanged ()
{
  invalidateFilter();
}

void MaterialDataSortFilterProxModel::SetFilter (const QString& filter)
{
  _filter = filter;
  invalidateFilter();
}

const QString& MaterialDataSortFilterProxModel::GetFilter () const
{
  return _filter;
}

bool MaterialDataSortFilterProxModel::filterAcceptsRow ( int sourceRow, const QModelIndex & sourceParent ) const
{
  if (_filter.length() == 0)
    {
      return true;
    }

  if (sourceParent.isValid())
    {
      return false;
    }

  MaterialData* data = _model->GetMaterialData(sourceRow);
  if (!data)
    {
      return false;
    }
  QString fullName = data->GetCategory().GetFullName() + "." + data->GetFullname();

  if (fullName.contains(_filter))
    {
      return true;
    }
  return false;
}
